package misc;

import java.util.LinkedList;
import java.util.Queue;

/**
 * Allocation cache. Prevents from useless GC work.
 */
public final class AllocCache<T> {
    public static abstract class Factory<T> {
        public abstract T create();
        public void release(T obj) {}
    }

    private final Factory<T> factory;
    public AllocCache(Factory<T> factory) {
        this.factory = factory;
    }

    private final Queue<T> cache = new LinkedList<T>();

    public synchronized T allocate() {
        T res;
        if (cache.isEmpty()) {
            res = factory.create();
        } else {
            res = cache.remove();
        }

        return res;
    }

    public synchronized void release(T obj) {
        factory.release(obj);

        cache.add(obj);
    }
}
